home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / ops5c.zip / WALTZ.C < prev    next >
C/C++ Source or Header  |  1989-07-10  |  4KB  |  167 lines

  1.  
  2. #include "o5c.h"
  3. #include <math.h>
  4.  
  5. #define PI        3.1415927
  6. #define MOD_NUM        10000
  7. #define get_y(val)    (val % MOD_NUM)
  8. #define get_x(val)    ((int) (val / MOD_NUM))
  9.  
  10.  
  11. int p1_offset, p2_offset, p3_offset;
  12. StrID tee_str_id, fork_str_id, arrow_str_id;
  13.  
  14. BOOLEAN first = TRUE;
  15.  
  16. void
  17. init()
  18. {
  19.     StringEntry str_entry;
  20.  
  21.     p1_offset = dollar_litbind("p1");
  22.     p2_offset = dollar_litbind("p2");
  23.     p3_offset = dollar_litbind("p3");
  24.  
  25.     str_entry = AddString("tee",attr_values);
  26.     tee_str_id = str_entry->str_id;
  27.     str_entry = AddString("fork",attr_values);
  28.     fork_str_id = str_entry->str_id;
  29.     str_entry = AddString("arrow",attr_values);
  30.     arrow_str_id = str_entry->str_id;
  31.  
  32.     first = FALSE;
  33. }
  34.  
  35.  
  36. /**********************************************************************
  37.  * This function is passed two points and calculates the angle between the
  38.  * line defined by these points and the x-axis.
  39.  **********************************************************************/
  40. float
  41. get_angle(p1,p2)
  42. int p1,p2;
  43. {
  44.     int delta_x, delta_y;
  45.  
  46.     /* Calculate (x2 - x1) and (y2 - y1).  The points are passed in the
  47.      * form x1y1 and x2y2.  get_x() and get_y() are passed these points
  48.      * and return the x and y values respectively.  For example,
  49.      * get_x(1020) returns 10. */
  50.     delta_x = get_x(p2) - get_x(p1);
  51.     delta_y = get_y(p2) - get_y(p1);
  52.  
  53.     if (delta_x == 0) {
  54.         if (delta_y > 0)
  55.             return(PI/2);
  56.         else if (delta_y < 0)
  57.             return(-PI/2);
  58.     }
  59.     else if (delta_y == 0) {
  60.         if (delta_x > 0)
  61.             return(0.0);
  62.         else if (delta_x < 0)
  63.             return(PI);
  64.     }
  65.     else
  66.         return((float) atan( ((float) delta_y) / ((float) delta_x)));
  67. }
  68.  
  69.  
  70. /**********************************************************************
  71.  * This procedure is passed the basepoint of the intersection of two lines
  72.  * as well as the other two endpoints of the lines and calculates the
  73.  * angle inscribed by these three points.
  74.  **********************************************************************/
  75. float
  76. inscribed_angle(basepoint,p1,p2)
  77. int basepoint, p1, p2;
  78. {
  79.     float angle1, angle2, temp;
  80.  
  81.     /* Get the angle between line #1 and the origin and the angle
  82.      * between line #2 and the origin, and then subtract these values. */
  83.     angle1 = get_angle(basepoint,p1);
  84.     angle2 = get_angle(basepoint,p2);
  85.     temp = angle1 - angle2;
  86.     if (temp < 0.0)
  87.         temp = -temp;
  88.  
  89.     /* We always want the smaller of the two angles inscribed, so if the
  90.      * answer is greater than 180 degrees, calculate the smaller angle and
  91.      * return it. */
  92.     if (temp > PI)
  93.         temp = 2*PI - temp;
  94.     if (temp < 0.0)
  95.         return(-temp);
  96.     return(temp);
  97. }
  98.  
  99.  
  100. void
  101. make_3_junction(argc)
  102. int argc;
  103. {
  104.     int basepoint,p1,p2,p3;
  105.     int shaft,barb1,barb2;
  106.     float angle12, angle13, angle23;
  107.     float sum, sum1213, sum1223, sum1323;
  108.     float delta;
  109.  
  110.     if (first)
  111.         init();
  112.  
  113.     basepoint = args[0].data.ival;
  114.     p1 = args[1].data.ival;
  115.     p2 = args[2].data.ival;
  116.     p3 = args[3].data.ival;
  117.  
  118.     angle12 = inscribed_angle(basepoint,p1,p2);
  119.     angle13 = inscribed_angle(basepoint,p1,p3);
  120.     angle23 = inscribed_angle(basepoint,p2,p3);
  121.  
  122.     sum1213 = angle12 + angle13;
  123.     sum1223 = angle12 + angle23;
  124.     sum1323 = angle13 + angle23;
  125.  
  126.     if (sum1213 < sum1223) {
  127.         if (sum1213 < sum1323) {
  128.             sum = sum1213;
  129.             shaft = p1; barb1 = p2; barb2 = p3;
  130.         }
  131.         else {
  132.             sum = sum1323;
  133.             shaft = p3; barb1 = p1; barb2 = p2;
  134.         }
  135.     }
  136.     else {
  137.         if (sum1223 < sum1323) {
  138.             sum = sum1223;
  139.             shaft = p2; barb1 = p1; barb2 = p3;
  140.         }
  141.         else {
  142.             sum = sum1323;
  143.             shaft = p3; barb1 = p1; barb2 = p2;
  144.         }
  145.     }
  146.  
  147.     delta = sum - PI;
  148.     if (delta < 0.0)
  149.         delta = -delta;
  150.  
  151.     if (delta < 0.001)
  152.         dollar_str_val(tee_str_id);
  153.     else if (sum > PI)
  154.         dollar_str_val(fork_str_id);
  155.     else
  156.         dollar_str_val(arrow_str_id);
  157.  
  158.     dollar_tab1(p1_offset);
  159.     dollar_int_val(barb1);
  160.  
  161.     dollar_tab1(p2_offset);
  162.     dollar_int_val(shaft);
  163.  
  164.     dollar_tab1(p3_offset);
  165.     dollar_int_val(barb2);
  166. }
  167.